﻿using System;
using System.Collections.Generic;
using System.IO;
using MatlabBridge.NativeMethods;

namespace MatlabBridge.IO
{
    public sealed class MatFile : IDisposable
    {
        private static string MatFileAccessToString(MatFileAccess access)
        {
            switch (access)
            {
                case MatFileAccess.Read: return "r";
                case MatFileAccess.Update: return "u";
                case MatFileAccess.Write: return "w";
                case MatFileAccess.WriteLevel4: return "w4";
                case MatFileAccess.WriteSystemCharSet: return "wL";
                case MatFileAccess.WriteCompressed: return "wz";
                case MatFileAccess.WriteHDF5: return "w7.3";
                default:
                    throw new ArgumentOutOfRangeException("access");
            }
        }

        public MatFile(string filename, MatFileAccess access)
        {
            this.mfp = libmat.matOpen(filename, MatFileAccessToString(access));
            MatlabException.ThrowException("Could not open .MAT file.", this.mfp);
        }

        ~MatFile()
        {
            this.Dispose(false);
        }
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected void Dispose(bool disposing)
        {
            if (disposing)
            {
            }

            if (mfp != IntPtr.Zero)
            {
                libmat.matClose(mfp);
                mfp = IntPtr.Zero;
            }
        }

        protected IntPtr mfp;
        public IntPtr UnmanagedPointer
        {
            get { return mfp; }
        }
        public IntPtr UnmanagedFileHandle
        {
            get { return libmat.matGetFp(mfp); }
        }

        public int Count
        {
            get
            {
                unsafe
                {
                    int num;
                    libmat.matGetDir(mfp, &num);
                    return num;
                }
            }
        }
    }
}
